<template>
  <div class="student-course-selection">
    <div class="header">
      <h2>选修课程</h2>
      <el-tag type="success" v-if="studentName">当前学生：{{ studentName }}</el-tag>
    </div>
    <el-tabs v-model="activeTab" @tab-click="handleTabChange">
      <el-tab-pane label="可选课程" name="available">
        <el-card class="search-card" shadow="never">
          <el-form :inline="true" :model="courseSearch" size="small">
            <el-form-item label="课程名">
              <el-input v-model="courseSearch.name" placeholder="输入课程名" clearable />
            </el-form-item>
            <el-form-item label="教师名">
              <el-input v-model="courseSearch.teacherName" placeholder="输入教师名" clearable />
            </el-form-item>
            <el-form-item>
              <el-button type="primary" @click="fetchAvailableCourses">查询</el-button>
              <el-button @click="resetAvailableSearch">重置</el-button>
            </el-form-item>
          </el-form>
        </el-card>
        <el-table :data="availableCourses" v-loading="loadingAvailable" stripe style="width:100%;margin-top:12px;">
          <el-table-column prop="id" label="课程ID" width="70" />
          <el-table-column prop="name" label="课程名" />
          <el-table-column prop="teacherName" label="教师" />
          <el-table-column prop="credit" label="学分" width="80" />
          <el-table-column prop="time" label="上课时间" min-width="120">
            <template slot-scope="scope">
              {{ formatTime(scope.row) }}
            </template>
          </el-table-column>
          <el-table-column prop="selectedCount" label="已选人数" width="90">
            <template slot-scope="scope">{{ scope.row.selectedCount ?? 0 }}</template>
          </el-table-column>
          <el-table-column prop="capacity" label="课程容量" width="90">
            <template slot-scope="scope">{{ scope.row.capacity ?? '-' }}</template>
          </el-table-column>
          <el-table-column label="操作" width="120">
            <template slot-scope="scope">
              <el-button size="mini" type="primary"
                @click="selectCourse(scope.row)"
                :disabled="selectingIds.has(scope.row.id) || isFull(scope.row) || isSelected(scope.row)">
                <i class="el-icon-check" /> 选修
              </el-button>
            </template>
          </el-table-column>
        </el-table>
        <div class="pagination-wrapper">
          <el-pagination
            background
            layout="total, prev, pager, next"
            :total="availableTotal"
            :page-size="availablePageSize"
            :current-page.sync="availablePage"
            @current-change="fetchAvailableCourses" />
        </div>
      </el-tab-pane>
      <el-tab-pane label="已选课程" name="selected">
        <el-table :data="mySelections" v-loading="loadingSelected" stripe style="width:100%;">
          <el-table-column prop="courseName" label="课程名称" />
          <el-table-column prop="teacherName" label="教师" />
          <el-table-column prop="dailyScore" label="平时分" width="90">
            <template slot-scope="s">{{ s.row.dailyScore ?? '-' }}</template>
          </el-table-column>
          <el-table-column prop="examScore" label="考试分" width="90">
            <template slot-scope="s">{{ s.row.examScore ?? '-' }}</template>
          </el-table-column>
          <el-table-column prop="score" label="总评" width="90">
            <template slot-scope="s">{{ s.row.score ?? '-' }}</template>
          </el-table-column>
          <el-table-column label="操作" width="160">
            <template slot-scope="scope">
              <el-popconfirm title="确定退选该课程吗？" @confirm="dropSelection(scope.row)">
                <el-button size="mini" type="danger" slot="reference">退选</el-button>
              </el-popconfirm>
            </template>
          </el-table-column>
        </el-table>
        <div class="pagination-wrapper">
          <el-pagination
            background
            layout="total, prev, pager, next"
            :total="selectedTotal"
            :page-size="selectedPageSize"
            :current-page.sync="selectedPage"
            @current-change="fetchMySelections" />
        </div>
      </el-tab-pane>
    </el-tabs>
  </div>
</template>
<script>
import { getStudentSelectableCoursePage, studentSelectCourse, studentDropCourse, getStudentCourseList } from '@/api'

export default {
  name: 'CourseSelectionStudent',
  data() {
    return {
      activeTab: 'available',
      studentName: '',
      studentId: null,
      // 可选课程查询条件
      courseSearch: { name: '', teacherName: '' },
      availableCourses: [],
      availablePage: 1,
      availablePageSize: 10,
      availableTotal: 0,
      loadingAvailable: false,
      selectingIds: new Set(),
      // 已选课程
      mySelections: [],
      selectedPage: 1,
      selectedPageSize: 10,
      selectedTotal: 0,
      loadingSelected: false
    }
  },
  created() {
    const info = this.$store.state.user.userInfo || JSON.parse(localStorage.getItem('userInfo')||'{}')
    this.studentName = info.username || info.name || ''
    this.studentId = info.id || info.studentId || null
    if (this.$store.state.user.userType !== 1) {
      this.$message.warning('当前不是学生身份，已跳转首页')
      this.$router.replace('/home')
      return
    }
    this.fetchAvailableCourses()
    this.fetchMySelections()
  },
  methods: {
    formatTime(row) {
      if (row.timeStr) return row.timeStr
      if (row.weekday && (row.sectionStart || row.sectionEnd)) {
        const weekMap = ['', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六', '星期日']
        const week = weekMap[row.weekday] || ''
        const secStart = row.sectionStart || row.section
        const secEnd = row.sectionEnd || row.section
        if (secStart && secEnd && secStart !== secEnd) return `${week}第${secStart}~${secEnd}节`
        if (secStart) return `${week}第${secStart}节`
      }
      return row.time || '-'
    },
    isFull(row) {
      return row.capacity && row.selectedCount >= row.capacity
    },
    isSelected(row) {
      if (!row) return false
      return this.mySelections.some(s => (s.courseId || s.id) === (row.id || row.courseId))
    },
    handleTabChange() {
      if (this.activeTab === 'available') this.fetchAvailableCourses()
      else this.fetchMySelections()
    },
    async fetchAvailableCourses() {
      this.loadingAvailable = true
      try {
        const listRes = await getStudentSelectableCoursePage(this.availablePage, this.courseSearch)
        let list = listRes.data || []
        if (process.env.NODE_ENV !== 'production') {
          console.debug('[StudentSelectable][RAW]', JSON.parse(JSON.stringify(list)))
        }
        const normalized = list.map(c => {
          const courseObj = c.course || {}
          const id = c.courseId || c.id || courseObj.id
          const name = c.name || c.courseName || courseObj.name
          const teacherName = c.teacherName || (c.teacher && c.teacher.name) || c.teacher || courseObj.teacherName || (courseObj.teacher && courseObj.teacher.name)
          const credit = c.credit || c.courseCredit || courseObj.credit
          const weekday = c.weekday != null ? c.weekday : courseObj.weekday
          const sectionStart = c.sectionStart != null ? c.sectionStart : courseObj.sectionStart
          const sectionEnd = c.sectionEnd != null ? c.sectionEnd : courseObj.sectionEnd
            // 统一时间字符串
          const time = c.time || c.timeStr || courseObj.time || courseObj.timeStr
          const selectedCount = c.selectedCount != null ? c.selectedCount : (c.currentSize != null ? c.currentSize : (c.enrolled != null ? c.enrolled : (courseObj.selectedCount != null ? courseObj.selectedCount : courseObj.currentSize)))
          const capacity = c.capacity != null ? c.capacity : (c.maxSize != null ? c.maxSize : (c.limit != null ? c.limit : (courseObj.capacity != null ? courseObj.capacity : (courseObj.maxSize != null ? courseObj.maxSize : courseObj.limit))))
          return { id, name, teacherName, credit, weekday, sectionStart, sectionEnd, time, selectedCount, capacity, raw: c }
        }).filter(c => c.id && c.name)
        if (this.mySelections.length) {
          const selectedIds = new Set(this.mySelections.map(s => (s.courseId || (s.course && s.course.id) || s.id)))
          this.availableCourses = normalized.filter(c => !selectedIds.has(c.id))
        } else {
          this.availableCourses = normalized
        }
        if (process.env.NODE_ENV !== 'production') {
          console.debug('[StudentSelectable][Normalized]', JSON.parse(JSON.stringify(this.availableCourses)))
        }
        this.availableTotal = this.availablePage * this.availablePageSize + (list.length === this.availablePageSize ? this.availablePageSize : 0)
      } catch (e) {
        console.error(e)
        this.$message.error('加载可选课程失败')
      } finally { this.loadingAvailable = false }
    },
    async fetchMySelections() {
      if (!this.studentName) return
      this.loadingSelected = true
      try {
        const res = await getStudentCourseList()
        const raw = res.data || []
        this.mySelections = raw.map(r => {
          const selectionId = r.id || r.selectionId || r.studentCourseId || r.scId || r.recordId
          const courseId = r.courseId || (r.course && r.course.id) || r.cid || r.id
          const courseName = r.courseName || (r.course && r.course.name) || r.name
          return {
            ...r,
            id: selectionId, // 确保表格使用的 id 是选课记录ID，用于退选
            selectionId,
            courseId,
            courseName
          }
        })
        if (process.env.NODE_ENV !== 'production') {
          console.debug('[StudentSelections][RAW]', JSON.parse(JSON.stringify(raw)))
          console.debug('[StudentSelections][Normalized]', JSON.parse(JSON.stringify(this.mySelections)))
        }
        this.selectedTotal = this.mySelections.length
      } catch (e) {
        console.error(e)
        this.$message.error('加载已选课程失败')
      } finally { this.loadingSelected = false }
    },
    resetAvailableSearch() {
      this.courseSearch = { name: '', teacherName: '' }
      this.availablePage = 1
      this.fetchAvailableCourses()
    },
    async selectCourse(row) {
      const courseId = row.id || row.courseId || (row.raw && (row.raw.courseId || (row.raw.course && row.raw.course.id)))
      if (!courseId) {
        this.$message.error('无法识别课程ID，选课失败')
        if (process.env.NODE_ENV !== 'production') {
          console.debug('[SelectCourse][ROW]', JSON.parse(JSON.stringify(row)))
        }
        return
      }
      this.selectingIds.add(courseId)
      try {
        if (process.env.NODE_ENV !== 'production') {
          console.debug('[SelectCourse][TRY]', courseId)
        }
        await studentSelectCourse(courseId)
        this.$message.success('选课成功')
        await this.fetchMySelections()
        await this.fetchAvailableCourses()
      } catch (e) {
        console.error(e)
        this.$message.error('选课失败')
      } finally { this.selectingIds.delete(courseId) }
    },
    async dropSelection(row) {
      // 可能出现后端没有直接给 selectionId，只能用多候选尝试
      const candidates = [
        row.selectionId,
        row.id, // 可能本身就是选课记录ID
        row.studentCourseId,
        row.scId,
        row.recordId,
        row.courseSelectionId,
        row.courseId, // 有些后端用课程ID退选
        row.course && row.course.id
      ].filter(v => v != null && v !== '' && v !== 'undefined')
      const tried = []
      for (const cid of candidates) {
        try {
          if (process.env.NODE_ENV !== 'production') {
            console.debug('[DropSelection][TRY]', cid)
          }
          await studentDropCourse(cid)
          this.$message.success('退选成功')
          await this.fetchMySelections()
          await this.fetchAvailableCourses()
          return
        } catch (e) {
          tried.push(cid)
          if (process.env.NODE_ENV !== 'production') {
            console.debug('[DropSelection][FAIL]', cid, e && e.response && e.response.data)
          }
        }
      }
      this.$message.error('退选失败：缺少有效选课记录ID')
      if (process.env.NODE_ENV !== 'production') {
        console.debug('[DropSelection][ROW]', JSON.parse(JSON.stringify(row)))
        console.debug('[DropSelection][TRIED]', tried)
      }
    }
  }
}
</script>
<style scoped>
.student-course-selection { padding:16px; }
.header { display:flex; align-items:center; gap:16px; margin-bottom:8px; }
.search-card { margin-bottom:12px; }
.pagination-wrapper { margin-top:12px; text-align:right; }
</style>
